﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using HalconDotNet;
using Go;

namespace fhs
{
    public partial class MainForm : Form
    {
        [DllImport("User32.dll")]
        private static extern bool GetCursorPos(out Point lpPoint);

        static public MainForm obj;
        StateForm _stateBar;
        HomeForm _homeForm;
        DebugForm _debugForm;
        DbShowForm _dbShowForm;
        LogViewForm _logViewForm;
        CurrProductForm _currProForm;
        long _lastMouseMoveTick;
        LoginForm.Mode _currMode;
        Dictionary<string, Control> _tabForms = new Dictionary<string, Control>();

        public MainForm()
        {
            obj = this;
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            GlobalData.mainStrand = new control_strand(this);
            _logViewForm = new LogViewForm();
            LogMgr.Info("软件启动");
            Init();
        }

        private async Task CheckUIDead()
        {
            bool sign = false;
            async_timer heartbeatTimer = new async_timer(GlobalData.mainStrand);
            GlobalData.mainStrand.post(() => heartbeatTimer.interval(3000, () => sign = true));
           
            while (true)
            {
                sign = false;
                await generator.sleep(10000);
                if (!sign)
                {
                    if (DialogResult.Yes == MessageBox.Show("程序UI停止响应！是否强制关闭进程？", "程序UI停止响应！", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
                    {
                        Process.GetCurrentProcess().Kill();
                    }
                    else
                    {
                        await generator.sleep(20000);
                    }
                }
            }
        }

        private void Init()
        {
            generator.tgo(GlobalData.mainStrand, async delegate ()
            {
                generator waitAct = generator.tgo(GlobalData.mainStrand, async delegate ()
                {
                    bool closed = false;
                    WaitForm waitForm = new WaitForm();
                    try
                    {
                        await generator.send_control(this, delegate ()
                        {
                            if (!closed)
                            {
                                waitForm.StartPosition = FormStartPosition.CenterParent;
                                waitForm.ShowDialog();
                            }
                        });
                    }
                    catch (generator.stop_exception)
                    {
                        closed = true;
                        waitForm.Close();
                        throw;
                    }
                });
                try
                {
                    if (Program.EnumCameras)
                    {
                        await generator.send_control(this, delegate ()
                        {
                            EnumCamerasForm enumCameras = new EnumCamerasForm();
                            enumCameras.ShowDialog();
                        });
                    }
                    await generator.send_task(delegate ()
                    {
                        InitOption.InitCard();
                        InitOption.InitComm();
                        InitOption.InitProduct();
                        InitOption.InitPoints();
                        InitOption.InitCamera();
                        InitOption.InitVision();
                        InitOption.InitLight();
                        InitOption.InitMotion();
                        InitOption.InitIo();
                    });
                    generator.go(new shared_strand(), CheckUIDead);
                    generator.go(GlobalData.mainStrand, DelaySwitchMode);

                    InitForm();
                    BtnStopState();
                    SwitchTabForm("home");
                    SwitchLoginMode(LoginForm.Mode.Debug);
                }
                catch (Exception ec)
                {
                    LogMgr.Error(ec.Message);
                    MessageBox.Show("初始化异常");
                    Process.GetCurrentProcess().Kill();
                    return;
                }
                await generator.stop_other(waitAct);
            });
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            LogMgr.Info("软件关闭");
            LogMgr.Close();
            Task.Run(delegate ()
            {
                System.Threading.Thread.Sleep(3000);
                Process.GetCurrentProcess().Kill();
            });
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult.No == MessageBox.Show("是否确定关闭？", "是否确定关闭？", MessageBoxButtons.YesNo))
            {
                e.Cancel = true;
            }
        }

        private async Task DelaySwitchMode()
        {
            Point lastPt = default(Point);
            _lastMouseMoveTick = system_tick.get_tick_ms();
            while (true)
            {
                await generator.sleep(100);
                Point currPt;
                GetCursorPos(out currPt);
                if (currPt != lastPt)
                {
                    lastPt = currPt;
                    _lastMouseMoveTick = system_tick.get_tick_ms();
                }
                if (LoginForm.Mode.Operator != _currMode && system_tick.get_tick_ms() - _lastMouseMoveTick > 10 * 60 * 1000)
                {
                    SwitchLoginMode(LoginForm.Mode.Operator);
                }
            }
        }

        private void InitForm()
        {
            {
                _stateBar = new StateForm();
                _stateBar.TopLevel = false;
                _stateBar.Dock = DockStyle.Fill;
                _stateBar.Visible = true;
                panel_state.Controls.Add(_stateBar);
            }
            {
                _homeForm = new HomeForm();
                _homeForm.TopLevel = false;
                _homeForm.Dock = DockStyle.Fill;
                _homeForm.Visible = false;
                panel_main.Controls.Add(_homeForm);
                _tabForms.Add("home", _homeForm);
            }
            {
                _debugForm = new DebugForm();
                _debugForm.TopLevel = false;
                _debugForm.Dock = DockStyle.Fill;
                _debugForm.Visible = false;
                panel_main.Controls.Add(_debugForm);
                _tabForms.Add("debug", _debugForm);
            }
            {
                _dbShowForm = new DbShowForm();
                _dbShowForm.TopLevel = false;
                _dbShowForm.Dock = DockStyle.Fill;
                _dbShowForm.Visible = false;
                panel_main.Controls.Add(_dbShowForm);
                _tabForms.Add("database", _dbShowForm);
            }
            {
                _currProForm = new CurrProductForm();
                _currProForm.TopLevel = false;
                _currProForm.Dock = DockStyle.Fill;
                _currProForm.Visible = true;
                _currProForm.label_currProduct.Text = ProductMgr.currProduct;
                panel_currPro.Controls.Add(_currProForm);
            }
        }

        private void SwitchTabForm(string tabName)
        {
            if (!_tabForms[tabName].Visible)
            {
                foreach (var form in _tabForms)
                {
                    form.Value.Visible = false;
                }
                _tabForms[tabName].Visible = true;
            }
        }

        private void SwitchBtnImage(Button btn, int idx, params Bitmap[] images)
        {
            btn.BackgroundImage = images[idx];
        }

        private void SwitchLoginMode(LoginForm.Mode mode)
        {
            if (_currMode == mode) return;
            LogMgr.Info($"模式切换到 {mode}");
            _currMode = mode;
            switch (mode)
            {
                case LoginForm.Mode.Operator:
                    EnableHomeBtn(true);
                    EnableDebugBtn(false);
                    EnableDbShowBtn(false);
                    SwitchTabForm("home");
                    break;
                case LoginForm.Mode.Debug:
                    EnableHomeBtn(true);
                    EnableDebugBtn(true);
                    EnableDbShowBtn(false);
                    SwitchTabForm("home");
                    break;
                case LoginForm.Mode.Engineer:
                    EnableHomeBtn(true);
                    EnableDebugBtn(true);
                    EnableDbShowBtn(true);
                    SwitchTabForm("home");
                    break;
                default:
                    break;
            }
        }

        private void button_home_Click(object sender, EventArgs e)
        {
            SwitchTabForm("home");
        }

        private void button_debug_Click(object sender, EventArgs e)
        {
            SwitchTabForm("debug");
        }

        private void button_data_Click(object sender, EventArgs e)
        {
            SwitchTabForm("database");
        }

        private void button_login_Click(object sender, EventArgs e)
        {
            LoginForm loginDlg = new LoginForm();
            loginDlg.StartPosition = FormStartPosition.CenterParent;
            loginDlg.ShowDialog();
            if (loginDlg._isLogin)
            {
                SwitchLoginMode(loginDlg._mode);
            }
        }

        private void button_run_Click(object sender, EventArgs e)
        {
            StateForm.obj.Run();
            BtnRunState();
            if (AutoAction.IsRun())
            {
                AutoAction.Resume();
                return;
            }
            if (!AutoAction.Start(delegate ()
            {
                StateForm.obj.Stop();
                BtnStopState();
            }, delegate (bool isPause)
            {
                if (isPause)
                {
                    StateForm.obj.Pause();
                    BtnPauseState();
                }
                else
                {
                    StateForm.obj.Run();
                    BtnRunState();
                }
            }))
            {
                StateForm.obj.Stop();
                BtnStopState();
            }
        }

        private void button_pause_Click(object sender, EventArgs e)
        {
            AutoAction.Pause();
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            AutoAction.Stop();
        }

        private void EnableHomeBtn(bool enable)
        {
            button_home.BackgroundImage = enable ? Properties.Resources.Home_on : Properties.Resources.Home_Off;
            button_home.Enabled = enable;
        }

        private void EnableDebugBtn(bool enable)
        {
            button_debug.BackgroundImage = enable ? Properties.Resources.Mannual_On : Properties.Resources.Mannual_Off;
            button_debug.Enabled = enable;
        }

        private void EnableDbShowBtn(bool enable)
        {
            button_data.BackgroundImage = enable ? Properties.Resources.data : Properties.Resources.data_off;
            button_data.Enabled = enable;
        }

        private void EnableRunBtn(bool enable)
        {
            button_run.BackgroundImage = enable ? Properties.Resources.Start_On : Properties.Resources.Start_Off;
            button_run.Enabled = enable;
        }

        private void EnablePauseBtn(bool enable)
        {
            button_pause.BackgroundImage = enable ? Properties.Resources.Pause_On : Properties.Resources.Pause_Off;
            button_pause.Enabled = enable;
        }

        private void EnableStopBtn(bool enable)
        {
            button_stop.BackgroundImage = enable ? Properties.Resources.Stop_On : Properties.Resources.Stop_Off;
            button_stop.Enabled = enable;
        }

        public void BtnRunState()
        {
            EnableRunBtn(false);
            EnablePauseBtn(true);
            EnableStopBtn(true);
        }

        public void BtnPauseState()
        {
            EnableRunBtn(true);
            EnablePauseBtn(false);
            EnableStopBtn(true);
        }

        public void BtnStopState()
        {
            EnableRunBtn(true);
            EnablePauseBtn(false);
            EnableStopBtn(false);
        }
    }
}
